'''
Created on Apr 5, 2009

@author: Administrator
'''
import time
from datetime import date, datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from com.ericyang.common import Callable
from com.ericyang.common.web.middleware import threadlocals
from com.ericyang.groupshopping.product.models import Product, Category
from com.ericyang.groupshopping.addressbook.models import AddressBook
from django.contrib.auth.models import User
from com.ericyang.groupshopping.user.models import UserDetail

class GroupOrder(models.Model):
     STATUS_CHIOSES = (
          ('0', _('order_status_inviting')),
          ('1', _('order_status_handling')),
          ('2', _('order_status_charging')),
          ('3', _('order_status_success')),
          ('4', _('order_status_failed')),
          ('5', _('order_status_canceled')),
     ) 
     LOWESET_ACCEPTABLE_PERCENTAGE = 50
     product = models.ForeignKey(Product, null=False)
     createUser = models.ForeignKey(UserDetail, null=False)
     title = models.CharField(max_length=200)
     status = models.CharField(max_length=1, choices=STATUS_CHIOSES)
     
     minUserNum = models.IntegerField(_("order min user number"), default=1)
     maxUserNum = models.IntegerField(_("order max user number"), default=1)
     minVendorNum = models.IntegerField(_("order min vendor number"), default=1)
     maxVendorNum = models.IntegerField(_("order max vendor number"), default=1)
     
     #proposal price 
     proposalPrice = models.DecimalField(_("proposal price"), max_digits=12, decimal_places=2)
     
     deadline = models.DateField(_('order dead line'), null=True)
     confirmTime = models.DateTimeField(_("order confirm time"), null=True)
     closeTime = models.DateTimeField(_("order close time"), null=True)
     createTime = models.DateTimeField(_("order create time"))
     
     def is_inviting(self):
         return self.status == "0"     
     def is_handling(self):
         return self.status == "1"     
     def is_charging(self):
         return self.status == "2"     
     def is_success(self):
         return self.status == "3"     
     def is_failed(self):
         return self.status == "4"     
     def is_canceled(self):
         return self.status == "5"
     
     def get_status(self):
         for key, value in GroupOrder.STATUS_CHIOSES:
             if self.status == key:
                 return value
         return ""
     
     def save(self):
        if self.createUser == None:
            self.createUser = threadlocals.get_current_user()
        super(GroupOrder, self).save()
    
     def order_users(self):
          return GroupOrderUser.objects.filter(order__id=self.id)
    
     def order_vendors(self):
         return GroupOrderVendor.objects.filter(order__id=self.id)
     
     def order_user_size(self):
          return self.order_users().count()
    
     def order_vendor_size(self):
         return self.order_vendors().count()
     
     def is_can_stop_inviting(self):
         if self.deadline < date.fromtimestamp(time.time()):
             self.cancel()
             return False
         return self.order_user_size() >= self.minUserNum and self.order_vendor_size() >= self.minVendorNum
     
     def get_order_user(self, user_id):
         queryset = GroupOrderUser.objects.filter(order__id=self.id, user__id=user_id)
         if queryset and queryset.count() > 0:
             return queryset[0]
         return None
     
     def get_order_vendor(self, vendor_id):
         queryset = GroupOrderVendor.objects.filter(order__id=self.id, user__id=vendor_id)
         if queryset and queryset.count() > 0:
             return queryset[0]
         return None
     
     def get_order_vendor_by_id(self, id):
         queryset = GroupOrderVendor.objects.filter(order__id=self.id, pk=id)
         if queryset and queryset.count() > 0:
             return queryset[0]
         return None
     
     
     def get_selected_vendor(self):
         queryset = GroupOrderVendor.objects.filter(order__id=self.id, status=GroupOrderVendor.STATUS_SELECTED)
         if queryset and queryset.count() == 1 :
             return queryset[0]
         return None
     
     def is_changable(self):
         return "0" == self.status
     
     def is_joinable(self):
         return int(self.status) < 2
         
     def is_cancelable(self):
         return self.is_belong() and int(self.status) < 3
     
     def is_belong(self):
         return self.createUser.id == threadlocals.get_current_user().id

     def cancel(self):
         print self.is_cancelable()
         if self.is_cancelable():
             self.status = "5"
             self.closeTime = datetime.now()
             self.save()
             
     def stop_inviting(self):
         if self.is_belong() and self.is_inviting() and self.is_can_stop_inviting():
             self.status = "1"
             self.closeTime = datetime.now()
             GroupOrderUser.objects.filter(order__id=self.id,
                                                status=GroupOrderUser.STATUS_DEFAULT).update(status=GroupOrderUser.STATUS_UNVOTED)
             self.save()
     
     def is_chargable(self):
         if self.is_belong() and self.is_handling():
             total_user_size = self.order_user_size()
             voted_users = GroupOrderUser.objects.filter(order__id=self.id, status=GroupOrderUser.STATUS_VOTED)
             voted_user_size = voted_users.count()
             if voted_user_size >= total_user_size / 2:
                 for vendor in self.order_vendors():
                     if vendor.voted_percentage() >= self.LOWESET_ACCEPTABLE_PERCENTAGE:
                         return True
         #==================
         return False
    
     def set_charging(self):
         if self.is_chargable():
             self.status = "2"
             GroupOrderUser.objects.filter(order__id=self.id,
                                                status=GroupOrderUser.STATUS_UNVOTED).update(status=GroupOrderUser.STATUS_OUT)
             self.save()
             
     def set_success(self):
         if self.is_belong() and self.is_charging():
             self.status = "3"
             self.confirmTime = datetime.now()
             self.save()
             
     def set_failed(self):
         if self.is_belong() and self.is_charging():
             self.status = "4"
             self.confirmTime = datetime.now()
             self.save()
             
     def is_valid_status_value(status_key):
         for key, value in GroupOrder.STATUS_CHIOSES:
             if status_key == key:
                 return True
         return False
     
     _STATUS_CHIOSES = (
          ('0', "inviting"),
          ('1', "handling"),
          ('2', "charging"),
          ('3', "success"),
          ('4', "failed"),
          ('5', "canceled"),
     )
     def is_valid_status(status):
         for key, value in GroupOrder._STATUS_CHIOSES:
             if status == value:
                 return True
         return False
     
     def get_status_value(status):
         for key, value in GroupOrder._STATUS_CHIOSES:
             if status == value:
                 return key
         return "0"

     is_valid_status_value = Callable(is_valid_status_value)
     get_status_value = Callable(get_status_value)
     is_valid_status = Callable(is_valid_status)

class GroupOrderVendor (models.Model):
    DELIVER_TYPE_CHIOSES = (
          ('0', _('vendor_deliver_send by express company')),
          ('1', _('vendor_deliver_get from storefront')),
          ('2', _('vendor_deliver_deliver to home')),
     )
    
    PAYMENT_TYPE_CHIOSES = (
          ('0', _('vendor_payment_web-bank payment')),
          ('1', _('vendor_payment_face-to-face payment')),
          ('2', _('vendor_payment_pay when delivering to home')),
     )
    
    STATUS_CHIOSES = (
          ('0', _('vendor_status_Hold')),
          ('1', _('vendor_status_Selected')),
          ('2', _('vendor_status_Voted out')),
    )
    STATUS_DEFAULT = STATUS_CHIOSES[0][0]
    STATUS_SELECTED = STATUS_CHIOSES[1][0]
    STATUS_OUT = STATUS_CHIOSES[2][0]
    
    order = models.ForeignKey(GroupOrder, null=False)
    user = models.ForeignKey(UserDetail, null=False)
    has_stored_product = models.BooleanField(_("vendor_has stored product"))
    deliver_type = models.CharField(_("vendor_deliver Type"), max_length=1, choices=DELIVER_TYPE_CHIOSES)
    payment_type = models.CharField(_("vendor_payment Type"), max_length=1, choices=PAYMENT_TYPE_CHIOSES)

    status = models.CharField(_("vendor_vendor status"), max_length=1, choices=STATUS_CHIOSES)
    
    def save(self):
        if self.user == None:
            self.user = threadlocals.get_current_user()
        super(GroupOrderVendor, self).save()
    
    def get_deliver_type(self):
        return DELIVER_TYPE_CHIOSES[self.deliver_type]
    
    def get_payment_type(self):
        return PAYMENT_TYPE_CHIOSES[self.payment_type]
    
    def company_name(self):
        return self.user.company_name()
    
    def voted_percentage(self):
        voted_users = GroupOrderUser.objects.filter(order__id=self.order.id,
                                                    selected_vendor__id=self.id,
                                                    status=GroupOrderUser.STATUS_VOTED)
        percentage = (voted_users.count() / self.order.order_user_size()) * 100
        return percentage
        #return percentage + "%"
    
    def quit_order(self):
        if self.order.is_changable():
            self.delete()
        else :
            self.status = self.STATUS_OUT
            self.save()
    
class GroupOrderUser(models.Model):
    STATUS_CHIOSES = (
          ('0', _('orderuser_status_Hold')),
          ('1', _('orderuser_status_Unvoted')),
          ('2', _('orderuser_status_Voted')),
          ('3', _('orderuser_status_Finished')),
          ('4', _('orderuser_status_Out')),
    )
    STATUS_DEFAULT = STATUS_CHIOSES[0][0]
    STATUS_UNVOTED = STATUS_CHIOSES[1][0]
    STATUS_VOTED = STATUS_CHIOSES[2][0]
    STATUS_FINISHED = STATUS_CHIOSES[3][0]
    STATUS_OUT = STATUS_CHIOSES[4][0]
    
    order = models.ForeignKey(GroupOrder, null=False)
    user = models.ForeignKey(UserDetail, null=False)
    address_book = models.ForeignKey(AddressBook, null=False)
    selected_vendor = models.ForeignKey(GroupOrderVendor, null=True)
    
    status = models.CharField(_("orderuser_status"), max_length=1, choices=STATUS_CHIOSES)
    
    def save(self):
        if self.user == None:
            self.user = threadlocals.get_current_user()
        if self.status == None or self.status == "":
            self.status = self.STATUS_DEFAULT
        super(GroupOrderUser, self).save()
    
    def vote(self, vendor):
        if vendor != None and (self.status == self.STATUS_UNVOTED or self.status == self.STATUS_VOTED):
            self.selected_vendor = vendor
            self.status = self.STATUS_VOTED
            self.save()
    
    def has_voted(self):
        return self.status == self.STATUS_VOTED
    
    def quit_order(self):
        if self.order.is_changable():
            self.delete()
        else :
            self.status = self.STATUS_OUT
            self.save()
    
